home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / os2 / sysb091a.zip / sysbench / src / pmb_main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-09  |  38.3 KB  |  1,229 lines

  1. // Sysbench main file
  2. //#define INCL_NOCOMMON
  3. #define INCL_DOSMISC
  4. #define INCL_DOSDEVICES
  5. #define INCL_DOSPROCESS
  6. #define INCL_DOSDEVIOCTL
  7. //#define INCL_DOSSEMAPHORES
  8. #define INCL_DOSERRORS
  9. #define INCL_WINWINDOWMGR
  10. #define INCL_WINMESSAGEMGR
  11. #define INCL_WINFRAMEMGR
  12. #define INCL_WINDIALOGS
  13. #define INCL_WININPUT
  14. #define INCL_WINSWITCHLIST
  15. #define INCL_WINPROGRAMLIST
  16. #define INCL_WINERRORS          /* Window Error Functions       */
  17. #define INCL_WINDESKTOP
  18. #define INCL_WINSTDFILE
  19. #define INCL_GPICONTROL
  20. #define INCL_GPIPRIMITIVES
  21.  
  22. #define INCL_WIN
  23. #define INCL_PM
  24. #define IDM_RESOURCE 1
  25. #define INCL_GPI
  26. #define INCL_GPILCIDS
  27. #define INCL_GPIPRIMITIVES
  28.  
  29. #include <os2.h>
  30. #include <time.h>
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include "types.h"
  35. #include "pmb.h"
  36. #include "pmb_bench.h"
  37. #include "pmb_datatype.h"
  38.  
  39. #define CLS_CLIENT   "SysBenchWindowClass"
  40. #define SYSB_VER     "0.9.1"
  41. #define THR_DONE     (WM_USER + 1)
  42. #define THR_UPDATE   (WM_USER + 2)
  43. #define START_STACKSIZE 65536
  44. #define DISP_LINES (75)
  45. #define MB           (1048576)
  46. #define KB            1024
  47. #define MN            1000000
  48.  
  49. // ********** IMPORTED FUNCTIONS
  50. extern int pmb_diskio_disksize(int nr);
  51. extern int pmb_diskio_nrdisks(void);
  52. extern void log(char* s);
  53.  
  54. // ********** EXPORTED FUNCTIONS
  55. void err(char* s);
  56. void InfoBox(char* s);
  57. void WarnBox(char* s);
  58. void ErrorBox(char* s);
  59.  
  60. // ********** LOCAL FUNCTIONS
  61. static void SetTitle(char* s);
  62. static void UpdateWindow(HPS hpsPaint, PRECTL pRect, s32 scrollValue);
  63. static void Print(s32 row, s32 col, char* string, PRECTL pRect,
  64.                   s32 scrollValue, HPS hpsPaint, s32 color);
  65. static void SetMenuState(bool active);
  66. static void UpdateAll(void);
  67. static void SaveResults(void);
  68. static void PrintFile(s32 newlines, s32 col, char* string, FILE* fp);
  69.  
  70. MRESULT EXPENTRY ClientWindowProc ( HWND hwndWnd,
  71.    ULONG ulMsg,
  72.    MPARAM mpParm1,
  73.    MPARAM mpParm2 );
  74.  
  75. // ********** EXPORTED DATA
  76. double test_time;
  77. static HWND   hwndClient = NULLHANDLE;
  78. static HWND   hwndVertScroll;
  79. static HWND   hwndMenu;
  80.  
  81. // ********** LOCAL DATA
  82. static bool thread_running;
  83. static s32  fontW;
  84. static s32  fontH;
  85. static HPS  mainHps = NULLHANDLE;
  86. //static HAB  hab = NULLHANDLE;
  87. static s32 scroll = 0;
  88. static s32 oldscroll = 0;
  89. static  HWND        hwndFrame = NULLHANDLE;
  90.  
  91. struct glob_data data = {
  92.   1,
  93.   1,
  94.   { 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 },
  95.   {
  96.     {
  97.       "Graphics",
  98.       8,
  99.       {
  100.         { "BitBlt S->S cpy",  -1.0, MN, "Mpixels/s" },
  101.         { "BitBlt M->S cpy",  -1.0, MN, "Mpixels/s" },
  102.         { "Filled Rectangle", -1.0, MN, "Mpixels/s" },
  103.         { "Pattern Fill",     -1.0, MN, "Mpixels/s" },
  104.         { "Vertical Lines",   -1.0, MN, "Mpixels/s" },
  105.         { "Horizontal Lines", -1.0, MN, "Mpixels/s" },
  106.         { "Diagonal Lines",   -1.0, MN, "Mpixels/s" },
  107.         { "Text Render",      -1.0, MN, "Mpixels/s" }
  108.       },
  109.       -1.0,
  110.       "PM-marks"
  111.     },
  112.     {
  113.       "CPU integer",
  114.       4,
  115.       {
  116.         { "Dhrystone",      -1.0, MN, "VAX 11/780 MIPS" },
  117.         { "Hanoi",          -1.0, 1, "moves/25 usec" },
  118.         { "Heapsort",       -1.0, MN, "MIPS" },
  119.         { "Sieve",          -1.0, MN, "MIPS" }
  120.       },
  121.       -1.0,
  122.       "CPUint-marks"
  123.     },
  124.     {
  125.       "CPU float",
  126.       3,
  127.       {
  128.         { "Linpack",            -1.0, 1000, "MFLOPS" },
  129.         { "Flops",              -1.0, MN, "MFLOPS" },
  130.         { "Fast Fourier Tr.",   -1.0, 1, "VAX FFT's" }
  131.       },
  132.       -1.0,
  133.       "CPUfloat-marks"
  134.     },
  135.     {
  136.       "Direct Interface to video extensions - DIVE",
  137.       3,
  138.       {
  139.         { "Video bus bandw.",    -1.0, MB, "MB/s" },
  140.         { "DIVE fun",            -1.0, 1, "fps at 640x480x256"  },
  141.         { "M->S, DD,   1.00:1",  -1.0, 1, "fps at 640x480x256"  }
  142.       },
  143.       -1.0,
  144.       "DIVE-marks"
  145.     },
  146.     {
  147.       "Disk I/O",
  148.       4,
  149.       {
  150.         { "Avg. data access time",   -1.0, 1.0e-03, "ms" },
  151.         { "Cache/Bus xfer rate  ",   -1.0, MB, "MB/s" },
  152.         { "Average Transfer rate",   -1.0, MB, "MB/s" },
  153.         { "Disk use CPU load    ",   -1.0, 1, "percent" }
  154.       },
  155.       -1.0,
  156.       "DiskIO-marks"
  157.     },
  158.     {
  159.       "Memory",
  160.       27,
  161.       {
  162.         { "5    kB copy", -1.0, MB, "MB/s" },
  163.         { "10   kB copy", -1.0, MB, "MB/s" },
  164.         { "20   kB copy", -1.0, MB, "MB/s" },
  165.         { "40   kB copy", -1.0, MB, "MB/s" },
  166.         { "80   kB copy", -1.0, MB, "MB/s" },
  167.         { "160  kB copy", -1.0, MB, "MB/s" },
  168.         { "320  kB copy", -1.0, MB, "MB/s" },
  169.         { "640  kB copy", -1.0, MB, "MB/s" },
  170.         { "1280 kB copy", -1.0, MB, "MB/s" },
  171.         { "5    kB read", -1.0, MB, "MB/s" },
  172.         { "10   kB read", -1.0, MB, "MB/s" },
  173.         { "20   kB read", -1.0, MB, "MB/s" },
  174.         { "40   kB read", -1.0, MB, "MB/s" },
  175.         { "80   kB read", -1.0, MB, "MB/s" },
  176.         { "160  kB read", -1.0, MB, "MB/s" },
  177.         { "320  kB read", -1.0, MB, "MB/s" },
  178.         { "640  kB read", -1.0, MB, "MB/s" },
  179.         { "1280 kB read", -1.0, MB, "MB/s" },
  180.         { "5    kB write", -1.0, MB, "MB/s" },
  181.         { "10   kB write", -1.0, MB, "MB/s" },
  182.         { "20   kB write", -1.0, MB, "MB/s" },
  183.         { "40   kB write", -1.0, MB, "MB/s" },
  184.         { "80   kB write", -1.0, MB, "MB/s" },
  185.         { "160  kB write", -1.0, MB, "MB/s" },
  186.         { "320  kB write", -1.0, MB, "MB/s" },
  187.         { "640  kB write", -1.0, MB, "MB/s" },
  188.         { "1280 kB write", -1.0, MB, "MB/s" },
  189.       },
  190.       -1.0,
  191.       "Mem-marks"
  192.     }
  193.   }
  194. };
  195.  
  196.  
  197. INT main ( VOID )
  198. {
  199.       FATTRS      fat;
  200.       LONG        match;
  201.       FONTMETRICS fmMetrics ;
  202.   HMQ         hmq = NULLHANDLE;
  203.   HAB         hab = NULLHANDLE;      /* PM anchor block handle         */
  204.   HAB         hab1 = NULLHANDLE;      /* PM anchor block handle         */
  205.   HWND  hwndDeskTop;
  206.   ERRORID     erridErrorCode;/* last error id code                   */
  207.   ULONG       flCreate = 0UL;
  208.   BOOL        bLoop;
  209.   QMSG        qmsg;
  210.   RECTL       rect;
  211.   s32         x,y,w,h, i;
  212.   MENUITEM    mi;
  213.   HWND        hwndPullDown;
  214.   CHAR        tmp[256];
  215.   int         rc = 1;
  216.  
  217.   if ( ( hab = WinInitialize ( 0UL ) ) == NULLHANDLE )
  218.         exit(2);
  219.  
  220.   if ( ( hmq = WinCreateMsgQueue ( hab, 0UL ) ) == NULLHANDLE )
  221.         exit(3);
  222.  
  223.   erridErrorCode = WinGetLastError(hab);
  224.  
  225.   rc = WinRegisterClass ( hab,
  226.                      CLS_CLIENT,
  227.                      ClientWindowProc,
  228.                      CS_SIZEREDRAW,       /*  CS_SYNCPAINT |  */
  229.                      0UL );
  230.  
  231.   erridErrorCode = WinGetLastError(hab);
  232.  
  233.   if ( rc != TRUE )
  234.  
  235.          {
  236.            log("WinRegisterClass failed") ;
  237.            exit(4);
  238.            }
  239.  
  240.  
  241.   flCreate = FCF_TITLEBAR | FCF_SYSMENU | FCF_SIZEBORDER | FCF_MENU |
  242.             FCF_MINMAX | FCF_TASKLIST | FCF_NOBYTEALIGN | FCF_VERTSCROLL;
  243.  
  244.   hwndDeskTop = WinQueryDesktopWindow(hab1,
  245.                                      NULLHANDLE);
  246.  
  247.   hwndFrame = WinCreateStdWindow( hwndDeskTop,
  248.                                    WS_VISIBLE,
  249.                                    &flCreate,
  250.                                    CLS_CLIENT,
  251.                                    SYSB_VER,
  252.                                    CS_SIZEREDRAW,
  253.                                    NULLHANDLE,
  254.                                    WND_MAIN,
  255.                                    &hwndClient );
  256.  
  257.    erridErrorCode = WinGetLastError(hab);
  258.  
  259.   if ( hwndFrame == NULLHANDLE )
  260.       {
  261.          log("hwndFrame is NULLHANDLE");
  262.          exit(6);
  263.       }
  264.  
  265.  
  266.   mainHps = WinGetPS(hwndClient);
  267.  
  268.   fat.usRecordLength = sizeof(FATTRS); /* sets size of structure   */
  269.   fat.fsSelection = 0;         /* uses default selection           */
  270.   fat.lMatch = 0;              /* does not force match             */
  271.   fat.idRegistry = 0;          /* uses default registry            */
  272.   fat.usCodePage = 0;          /* code-page 850                    */
  273.   fat.lMaxBaselineExt = 12L;   /* requested font height is 12 pels */
  274.   fat.lAveCharWidth = 8L;      /* requested font width is 12 pels  */
  275.   fat.fsType = 0;              /* uses default type                */
  276.   fat.fsFontUse = 0;           /* doesn't mix with graphics */
  277.  
  278.   strcpy(fat.szFacename ,"System VIO");
  279.  
  280.   match = GpiCreateLogFont(mainHps,        /* presentation space               */
  281.                            NULL,       /* does not use logical font name   */
  282.                            1L,         /* local identifier                 */
  283.                            &fat);      /* structure with font attributes   */
  284.  
  285.   // match should now be 2 == FONT_MATCH */
  286.  
  287.    if (match != FONT_MATCH) {
  288.     log("Can't get the right font");
  289.     exit(1);
  290.   }
  291.  
  292.   GpiSetCharSet(mainHps, 1L);      /* sets font for presentation space */
  293.  
  294.   GpiQueryFontMetrics ( mainHps,
  295.                         sizeof ( fmMetrics ) ,
  296.                         &fmMetrics ) ;
  297.  
  298.   fontH = (14 * fmMetrics.lMaxBaselineExt)/10;
  299.   fontW = fmMetrics.lMaxCharInc;
  300.  
  301.   GpiSetBackMix( mainHps, BM_OVERPAINT );  // how it mixes,
  302.   GpiSetMix( mainHps, FM_OVERPAINT );  // how it mixes,
  303.  
  304.   hwndVertScroll = WinWindowFromID( hwndFrame, FID_VERTSCROLL);
  305.  
  306.   WinQueryWindowRect(HWND_DESKTOP, &rect);
  307.   w = 636;
  308.   h = (rect.yTop-rect.yBottom) - 40;
  309.   x = (rect.xRight-rect.xLeft)/2 - w/2;
  310.   y = 40;
  311.   WinSetWindowPos(hwndFrame, false, x, y, w, h, SWP_SIZE | SWP_MOVE | SWP_ACTIVATE);
  312.  
  313.   WinQueryWindowRect(hwndClient, &rect);
  314.  
  315.   WinSendMsg( hwndVertScroll,
  316.               SBM_SETSCROLLBAR,
  317.               MPFROMSHORT(0),
  318.               MPFROM2SHORT(0, (DISP_LINES * fontH) - (rect.yTop - rect.yBottom)));
  319.  
  320.   WinSendMsg( hwndVertScroll,
  321.               SBM_SETTHUMBSIZE,
  322.               MPFROM2SHORT(rect.yTop - rect.yBottom, DISP_LINES * fontH),
  323.               NULL);
  324.  
  325.   SetTitle("Ready");
  326.  
  327.   thread_running = false;
  328.  
  329.  
  330.   data.nr_fixed_disks = pmb_diskio_nrdisks();
  331.   if (data.nr_fixed_disks > MAX_FIXED_DISKS) {
  332.     log("Number of fixed disks is too high");
  333.     exit(1);
  334.   }
  335.  
  336.   for (i = 0; i < data.nr_fixed_disks; i++) {
  337.     data.fixed_disk_size[i] = pmb_diskio_disksize(i);
  338.     sprintf(tmp, "Disk %d: %d MB", i+1, data.fixed_disk_size[i]/(MB));
  339.     hwndMenu = WinWindowFromID(hwndFrame, FID_MENU);
  340.     WinSendMsg(hwndMenu, MM_QUERYITEM, MPFROM2SHORT(MI_MENU_DISKIO_SELECT, TRUE),
  341.                (MPARAM) &mi);
  342.     hwndPullDown = mi.hwndSubMenu;
  343.     mi.iPosition = MIT_END;
  344.     mi.afStyle = MIS_TEXT;
  345.     mi.afAttribute = 0;
  346.     mi.id = MI_MENU_DISKIO_SELECT+1+i;
  347.     mi.hwndSubMenu = null;
  348.     mi.hItem = 0;
  349.     WinSendMsg(hwndPullDown, MM_INSERTITEM, (MPARAM) &mi,
  350.                (MPARAM)tmp);
  351.   }
  352.  
  353.   if (!data.nr_fixed_disks) {
  354.     hwndMenu = WinWindowFromID(hwndFrame, FID_MENU);
  355.     WinSendMsg(hwndMenu, MM_QUERYITEM, MPFROM2SHORT(MI_MENU_DISKIO_SELECT, TRUE),
  356.                (MPARAM) &mi);
  357.     hwndPullDown = mi.hwndSubMenu;
  358.     mi.iPosition = MIT_END;
  359.     mi.afStyle = MIS_TEXT;
  360.     mi.afAttribute = 0;
  361.     mi.id = MI_MENU_DISKIO_SELECT+1;
  362.     mi.hwndSubMenu = null;
  363.     mi.hItem = 0;
  364.     WinSendMsg(hwndPullDown, MM_INSERTITEM, (MPARAM) &mi,
  365.                (MPARAM)"No fixed disks found");
  366.  
  367.     WinEnableMenuItem(hwndMenu, MI_MENU_DISKIO, false);
  368.   } else {
  369.     hwndMenu = WinWindowFromID(hwndFrame, FID_MENU);
  370.     WinCheckMenuItem(hwndMenu, MI_MENU_DISKIO_SELECT + 1, true);
  371.     data.selected_disk = 0;
  372.     sprintf(data.c[comp_disk].title, "Disk I/O - disk %d: %d MB", data.selected_disk+1, data.fixed_disk_size[data.selected_disk]/(MB));
  373.   }
  374.  
  375.   WinEnableMenuItem(hwndMenu, MI_MENU_DIVE, true);
  376.  
  377.   UpdateAll();
  378.  
  379.   if ( hwndFrame != NULLHANDLE ) {
  380.     bLoop = WinGetMsg ( hab,
  381.                         &qmsg,
  382.                         NULLHANDLE,
  383.                         0,
  384.                         0 );
  385.     while ( bLoop ) {
  386.        WinDispatchMsg ( hab, &qmsg );
  387.        bLoop = WinGetMsg ( hab,
  388.                            &qmsg,
  389.                            NULLHANDLE,
  390.                            0,
  391.                            0 );
  392.     }
  393.  
  394.     WinReleasePS(mainHps);
  395.     WinDestroyWindow ( hwndFrame );
  396.   }
  397.  
  398.   WinDestroyMsgQueue ( hmq );
  399.   WinTerminate ( hab );
  400.   return 0;
  401. }
  402.  
  403. MRESULT EXPENTRY ClientWindowProc ( HWND hwndWnd,
  404.                                  ULONG ulMsg,
  405.                                  MPARAM mpParm1,
  406.                                  MPARAM mpParm2 )
  407. {
  408.   void *pv = null;
  409.   static bool initialized = false;
  410.   RECTL rect;
  411.   s32 tmp;
  412.   bool updateScroll;
  413.   QMSG qmsgPeek;
  414.   bool fDone;
  415.   char tmps[256];
  416.  
  417.   switch ( ulMsg ) {
  418.  
  419.   case WM_CREATE:
  420.     /* The client window has been created but is not visible yet.        */
  421.     /* Initialize the window here.                                       */
  422.     break;
  423.  
  424.   case WM_COMMAND:
  425.  
  426.     if (thread_running) {
  427.       switch (SHORT1FROMMP(mpParm1)) {
  428.       case MI_PROJ_QUIT:
  429.         WinPostMsg(hwndWnd, WM_CLOSE, NULL, NULL);
  430.         break;
  431.       case MI_PROJ_ABOUT:
  432.         InfoBox("SysBench "SYSB_VER" by Henrik Harmsen 1994-10-01.\n\nBug fixes by Trevor Hemsley 1996-05-18\nEmail: Trevor-Hemsley@dial.pipex.com\n"
  433.                 "Thanks to Kai Uwe Rommel for the disk IO tests, and Al Aburto for the CPU tests.");
  434.         break;
  435.       }
  436.       return false;
  437.     }
  438.  
  439.     if ((SHORT1FROMMP(mpParm1) > MI_MENU_DISKIO_SELECT) &&
  440.         (SHORT1FROMMP(mpParm1) <= (data.nr_fixed_disks + MI_MENU_DISKIO_SELECT))) {
  441.       s32 i, disk;
  442.       disk = SHORT1FROMMP(mpParm1) - (MI_MENU_DISKIO_SELECT + 1);
  443.       if (disk == data.selected_disk)
  444.         return false;
  445.       data.selected_disk = disk;
  446.       for (i = 0; i < data.nr_fixed_disks; i++) {
  447.         WinCheckMenuItem(hwndMenu, MI_MENU_DISKIO_SELECT + i + 1, false);
  448.       }
  449.       WinCheckMenuItem(hwndMenu, MI_MENU_DISKIO_SELECT + data.selected_disk + 1, true);
  450.       sprintf(data.c[comp_disk].title, "Disk I/O - disk %d: %d MB", data.selected_disk+1, data.fixed_disk_size[data.selected_disk]/(MB));
  451.       data.c[comp_disk].datalines[disk_avseek].value = -1.0;
  452.       data.c[comp_disk].datalines[disk_busxfer].value = -1.0;
  453.       data.c[comp_disk].datalines[disk_transf].value = -1.0;
  454.       data.c[comp_disk].datalines[disk_cpupct].value = -1.0;
  455.       data.c[comp_disk].total = -1.0;
  456.       UpdateAll();
  457.       return false;
  458.     }
  459.  
  460.     switch (SHORT1FROMMP(mpParm1)) {
  461.     case MI_PROJ_QUIT:
  462.       WinPostMsg(hwndWnd, WM_CLOSE, NULL, NULL);
  463.       break;
  464.     case MI_PROJ_ABOUT:
  465.         InfoBox("SysBench "SYSB_VER" by Henrik Harmsen 1994-10-01.\n\nBug fixes by Trevor Hemsley 1996-05-18\nEmail: Trevor-Hemsley@dial.pipex.com\n"
  466.                 "\nThanks to Kai Uwe Rommel for the disk IO tests, and Al Aburto for the CPU tests.");
  467.       break;
  468.     case MI_PROJ_SAVE:
  469.       SaveResults();
  470.       break;
  471.     case MI_PROJ_ALL:
  472.       SetTitle("Running All tests");
  473.       SetMenuState(false);
  474.       _beginthread(DoAll, null, START_STACKSIZE, pv);
  475.       break;
  476.     case MI_GFX_BITBLIT_SS:
  477.       SetTitle("Running BitBlit S->S");
  478.       SetMenuState(false);
  479.       _beginthread(DoGfxBlitBlitSS, null, START_STACKSIZE, pv);
  480.       break;
  481.     case MI_GFX_BITBLIT_MS:
  482.       SetTitle("Running BitBlit M->S");
  483.       SetMenuState(false);
  484.       _beginthread(DoGfxBlitBlitMS, null, START_STACKSIZE, pv);
  485.       break;
  486.     case MI_GFX_FILLRECT:
  487.       SetTitle("Running Filled Rectangle");
  488.       SetMenuState(false);
  489.       _beginthread(DoGfxFillRect, null, START_STACKSIZE, pv);
  490.       break;
  491.     case MI_GFX_PATFIL:
  492.       SetTitle("Running Pattern Fill");
  493.       SetMenuState(false);
  494.       _beginthread(DoGfxPatFil, null, START_STACKSIZE, pv);
  495.       break;
  496.     case MI_GFX_VLINES:
  497.       SetTitle("Running VerticalLines");
  498.       SetMenuState(false);
  499.       _beginthread(DoGfxVLines, null, START_STACKSIZE, pv);
  500.       break;
  501.     case MI_GFX_HLINES:
  502.       SetTitle("Running HorizontalLines");
  503.       SetMenuState(false);
  504.       _beginthread(DoGfxHLines, null, START_STACKSIZE, pv);
  505.       break;
  506.     case MI_GFX_DLINES:
  507.       SetTitle("Running DiagonalLines");
  508.       SetMenuState(false);
  509.       _beginthread(DoGfxDLines, null, START_STACKSIZE, pv);
  510.       break;
  511.     case MI_GFX_TEXTRENDER:
  512.       SetTitle("Running TextRender");
  513.       SetMenuState(false);
  514.       _beginthread(DoGfxTextRender, null, START_STACKSIZE, pv);
  515.       break;
  516.     case MI_GFX_ALL:
  517.       SetTitle("Running All Graphics tests");
  518.       SetMenuState(false);
  519.       _beginthread(DoAllGraphics, null, START_STACKSIZE, pv);
  520.       break;
  521.     case MI_CPUINT_DHRY:
  522.       SetTitle("Running Dhrystone");
  523.       SetMenuState(false);
  524.       _beginthread(DoCPUIntDhry, null, START_STACKSIZE, pv);
  525.       break;
  526.     case MI_CPUINT_HANOI:
  527.       SetTitle("Running Hanoi");
  528.       SetMenuState(false);
  529.       _beginthread(DoCPUIntHanoi, null, START_STACKSIZE, pv);
  530.       break;
  531.     case MI_CPUINT_HEAPS:
  532.       SetTitle("Running Heapsort");
  533.       SetMenuState(false);
  534.       _beginthread(DoCPUIntHeaps, null, START_STACKSIZE, pv);
  535.       break;
  536.     case MI_CPUINT_SIEVE:
  537.       SetTitle("Running Sieve");
  538.       SetMenuState(false);
  539.       _beginthread(DoCPUIntSieve, null, START_STACKSIZE, pv);
  540.       break;
  541.     case MI_CPUINT_ALL:
  542.       SetTitle("Running All CPU integer tests");
  543.       SetMenuState(false);
  544.       _beginthread(DoAllCPUInt, null, START_STACKSIZE, pv);
  545.       break;
  546.     case MI_CPUFLOAT_LINPACK:
  547.       SetTitle("Running Linpack");
  548.       SetMenuState(false);
  549.       _beginthread(DoCPUFloatLinpack, null, START_STACKSIZE, pv);
  550.       break;
  551.     case MI_CPUFLOAT_FLOPS:
  552.       SetTitle("Running FLOPS");
  553.       SetMenuState(false);
  554.       _beginthread(DoCPUFloatFlops, null, START_STACKSIZE, pv);
  555.       break;
  556.     case MI_CPUFLOAT_FFT:
  557.       SetTitle("Running FFT");
  558.       SetMenuState(false);
  559.       _beginthread(DoCPUFloatFFT, null, START_STACKSIZE, pv);
  560.       break;
  561.     case MI_CPUFLOAT_ALL:
  562.       SetTitle("Running All CPU float tests");
  563.       SetMenuState(false);
  564.       _beginthread(DoAllCPUFloat, null, START_STACKSIZE, pv);
  565.       break;
  566.     case MI_MEM_5:
  567.       SetTitle("Running Memcopy 5kB");
  568.       SetMenuState(false);
  569.       _beginthread(DoMem5, null, START_STACKSIZE, pv);
  570.       break;
  571.     case MI_MEM_10:
  572.       SetTitle("Running Memcopy 10kB");
  573.       SetMenuState(false);
  574.       _beginthread(DoMem10, null, START_STACKSIZE, pv);
  575.       break;
  576.     case MI_MEM_20:
  577.       SetTitle("Running Memcopy 20kB");
  578.       SetMenuState(false);
  579.       _beginthread(DoMem20, null, START_STACKSIZE, pv);
  580.       break;
  581.     case MI_MEM_40:
  582.       SetTitle("Running Memcopy 40kB");
  583.       SetMenuState(false);
  584.       _beginthread(DoMem40, null, START_STACKSIZE, pv);
  585.       break;
  586.     case MI_MEM_80:
  587.       SetTitle("Running Memcopy 80kB");
  588.       SetMenuState(false);
  589.       _beginthread(DoMem80, null, START_STACKSIZE, pv);
  590.       break;
  591.     case MI_MEM_160:
  592.       SetTitle("Running Memcopy 160kB");
  593.       SetMenuState(false);
  594.       _beginthread(DoMem160, null, START_STACKSIZE, pv);
  595.       break;
  596.     case MI_MEM_320:
  597.       SetTitle("Running Memcopy 320kB");
  598.       SetMenuState(false);
  599.       _beginthread(DoMem320, null, START_STACKSIZE, pv);
  600.       break;
  601.     case MI_MEM_640:
  602.       SetTitle("Running Memcopy 640kB");
  603.       SetMenuState(false);
  604.       _beginthread(DoMem640, null, START_STACKSIZE, pv);
  605.       break;
  606.     case MI_MEM_1280:
  607.       SetTitle("Running Memcopy 1280kB");
  608.       SetMenuState(false);
  609.       _beginthread(DoMem1280, null, START_STACKSIZE, pv);
  610.       break;
  611.     case MI_MEMR_5:
  612.       SetTitle("Running Memory Read 5kB");
  613.       SetMenuState(false);
  614.       _beginthread(DoMemR5, null, START_STACKSIZE, pv);
  615.       break;
  616.     case MI_MEMR_10:
  617.       SetTitle("Running Memory Read 10kB");
  618.       SetMenuState(false);
  619.       _beginthread(DoMemR10, null, START_STACKSIZE, pv);
  620.       break;
  621.     case MI_MEMR_20:
  622.       SetTitle("Running Memory Read 20kB");
  623.       SetMenuState(false);
  624.       _beginthread(DoMemR20, null, START_STACKSIZE, pv);
  625.       break;
  626.     case MI_MEMR_40:
  627.       SetTitle("Running Memory Read 40kB");
  628.       SetMenuState(false);
  629.       _beginthread(DoMemR40, null, START_STACKSIZE, pv);
  630.       break;
  631.     case MI_MEMR_80:
  632.       SetTitle("Running Memory Read 80kB");
  633.       SetMenuState(false);
  634.       _beginthread(DoMemR80, null, START_STACKSIZE, pv);
  635.       break;
  636.     case MI_MEMR_160:
  637.       SetTitle("Running Memory Read 160kB");
  638.       SetMenuState(false);
  639.       _beginthread(DoMemR160, null, START_STACKSIZE, pv);
  640.       break;
  641.     case MI_MEMR_320:
  642.       SetTitle("Running Memory Read 320kB");
  643.       SetMenuState(false);
  644.       _beginthread(DoMemR320, null, START_STACKSIZE, pv);
  645.       break;
  646.     case MI_MEMR_640:
  647.       SetTitle("Running Memory Read 640kB");
  648.       SetMenuState(false);
  649.       _beginthread(DoMemR640, null, START_STACKSIZE, pv);
  650.       break;
  651.     case MI_MEMR_1280:
  652.       SetTitle("Running Memory Read 1280kB");
  653.       SetMenuState(false);
  654.       _beginthread(DoMemR1280, null, START_STACKSIZE, pv);
  655.       break;
  656.     case MI_MEMW_5:
  657.       SetTitle("Running Memory Write 5kB");
  658.       SetMenuState(false);
  659.       _beginthread(DoMemW5, null, START_STACKSIZE, pv);
  660.       break;
  661.     case MI_MEMW_10:
  662.       SetTitle("Running Memory Write 10kB");
  663.       SetMenuState(false);
  664.       _beginthread(DoMemW10, null, START_STACKSIZE, pv);
  665.       break;
  666.     case MI_MEMW_20:
  667.       SetTitle("Running Memory Write 20kB");
  668.       SetMenuState(false);
  669.       _beginthread(DoMemW20, null, START_STACKSIZE, pv);
  670.       break;
  671.     case MI_MEMW_40:
  672.       SetTitle("Running Memory Write 40kB");
  673.       SetMenuState(false);
  674.       _beginthread(DoMemW40, null, START_STACKSIZE, pv);
  675.       break;
  676.     case MI_MEMW_80:
  677.       SetTitle("Running Memory Write 80kB");
  678.       SetMenuState(false);
  679.       _beginthread(DoMemW80, null, START_STACKSIZE, pv);
  680.       break;
  681.     case MI_MEMW_160:
  682.       SetTitle("Running Memory Write 160kB");
  683.       SetMenuState(false);
  684.       _beginthread(DoMemW160, null, START_STACKSIZE, pv);
  685.       break;
  686.     case MI_MEMW_320:
  687.       SetTitle("Running Memory Write 320kB");
  688.       SetMenuState(false);
  689.       _beginthread(DoMemW320, null, START_STACKSIZE, pv);
  690.       break;
  691.     case MI_MEMW_640:
  692.       SetTitle("Running Memory Write 640kB");
  693.       SetMenuState(false);
  694.       _beginthread(DoMemW640, null, START_STACKSIZE, pv);
  695.       break;
  696.     case MI_MEMW_1280:
  697.       SetTitle("Running Memory Write 1280kB");
  698.       SetMenuState(false);
  699.       _beginthread(DoMemW1280, null, START_STACKSIZE, pv);
  700.       break;
  701.     case MI_MEM_ALL:
  702.       SetTitle("Running All Memory tests");
  703.       SetMenuState(false);
  704.       _beginthread(DoAllMem, null, START_STACKSIZE, pv);
  705.       break;
  706.     case MI_DIVE_VIDEO_BW:
  707.       SetTitle("Running Video Bandwidth");
  708.       SetMenuState(false);
  709.       _beginthread(DoDiveVBW, null, START_STACKSIZE, pv);
  710.       break;
  711.     case MI_DIVE_ROTATE_SCREEN:
  712.       SetTitle("Running DIVE fun");
  713.       SetMenuState(false);
  714.       _beginthread(DoDiveRot, null, START_STACKSIZE, pv);
  715.       break;
  716.     case MI_DIVE_MS_11:
  717.       SetTitle("Running DIVE M->S 1:1");
  718.       SetMenuState(false);
  719.       _beginthread(DoDiveMS11, null, START_STACKSIZE, pv);
  720.       break;
  721.     case MI_DIVE_ALL:
  722.       SetTitle("Running All DIVE tests");
  723.       SetMenuState(false);
  724.       _beginthread(DoAllDIVE, null, START_STACKSIZE, pv);
  725.       break;
  726.     case MI_DISKIO_AVSEEK:
  727.       SetTitle("Running Average Seek Time");
  728.       SetMenuState(false);
  729.       _beginthread(DoDiskIOAvSeek, null, START_STACKSIZE, pv);
  730.       break;
  731.     case MI_DISKIO_CBXFER:
  732.       SetTitle("Running Cache/Bus Transfer");
  733.       SetMenuState(false);
  734.       _beginthread(DoDiskCacheXfer, null, START_STACKSIZE, pv);
  735.       break;
  736.     case MI_DISKIO_TRANS_SPEED:
  737.       SetTitle("Running Max. transfer speed");
  738.       SetMenuState(false);
  739.       _beginthread(DoDiskIOTransSpeed, null, START_STACKSIZE, pv);
  740.       break;
  741.     case MI_DISKIO_CPU_USAGE:
  742.       SetTitle("Running CPU Usage percentage");
  743.       SetMenuState(false);
  744.       _beginthread(DoDiskIOCPUUsage, null, START_STACKSIZE, pv);
  745.       break;
  746.     case MI_DISKIO_ALL:
  747.       SetTitle("Running All disk IO tests");
  748.       SetMenuState(false);
  749.       _beginthread(DoAllDiskIO, null, START_STACKSIZE, pv);
  750.       break;
  751.     }
  752.     break;
  753.  
  754.   case WM_PAINT:
  755.     {
  756.       FATTRS      fat;
  757.       LONG        match;
  758.       FONTMETRICS fmMetrics ;
  759.       HPS               hpsPaint ;
  760.       RECTL             rclRect ;
  761.       RECTL             rclWindow ;
  762.       ULONG             ulCharHeight ;
  763.       HWND              hwndEnum ;
  764.       HWND              hwndFrame ;
  765.       HENUM             heEnum ;
  766.       POINTL            point;
  767.       HRGN              newHrgn, oldHrgn, dummy;
  768.       s32               complexity;
  769.       RECTL             clipRect;
  770.  
  771.       if (!initialized) {
  772.         initialized = true;
  773.       }
  774.  
  775.       hpsPaint = WinBeginPaint ( hwndWnd,
  776.                                  NULLHANDLE,
  777.                                  &rclRect ) ;
  778.  
  779. // This should work, but there was a bug in Warp II
  780. //      newHrgn = GpiQueryClipRegion(hpsPaint);
  781. //      complexity = GpiSetClipRegion(mainHps, newHrgn, &oldHrgn);
  782. //      WinEndPaint(hpsPaint);
  783.  
  784.       GpiQueryClipBox(hpsPaint, &clipRect);
  785.       clipRect.xRight++;
  786.       clipRect.yTop++;
  787.       newHrgn = GpiCreateRegion(mainHps, 1, &clipRect);
  788.       GpiSetClipRegion(mainHps, newHrgn, &oldHrgn);
  789.       if (NULLHANDLE != oldHrgn) {
  790.         GpiDestroyRegion(mainHps, oldHrgn);
  791.       }
  792.  
  793.       WinFillRect(mainHps, &rclRect, CLR_BLACK);
  794.  
  795.       WinQueryWindowRect ( hwndWnd, &rclWindow );
  796.       UpdateWindow(mainHps,
  797.                    &rclWindow,
  798.                    scroll);
  799.  
  800.       oldscroll = scroll;
  801.       WinEndPaint(hpsPaint);
  802.     }
  803.     break;
  804.  
  805.   case THR_DONE:
  806.     SetTitle("Ready");
  807.     SetMenuState(true);
  808.     thread_running = false;
  809.     break;
  810.  
  811.   case THR_UPDATE:
  812.     UpdateAll();
  813.     break;
  814.  
  815.   case WM_SIZE:
  816.     {
  817.       s32 tmp;
  818.  
  819.       WinQueryWindowRect(hwndClient, &rect);
  820.  
  821.       tmp = DISP_LINES * fontH - (rect.yTop - rect.yBottom);
  822.  
  823.       if (tmp < 0) tmp = 0;
  824.       if (scroll > tmp) scroll = tmp;
  825.  
  826.       WinSendMsg( hwndVertScroll,
  827.                   SBM_SETSCROLLBAR,
  828.                   MPFROMSHORT(scroll),
  829.                   MPFROM2SHORT(0, tmp));
  830.  
  831.       WinSendMsg( hwndVertScroll,
  832.                   SBM_SETTHUMBSIZE,
  833.                   MPFROM2SHORT(rect.yTop - rect.yBottom, DISP_LINES * fontH),
  834.                   NULL);
  835.  
  836.     }
  837.     break;
  838.  
  839.   case WM_VSCROLL:
  840.     updateScroll = false;
  841.     WinQueryWindowRect(hwndClient, &rect);
  842.     switch( SHORT2FROMMP( mpParm2) )
  843.     {
  844.     case SB_LINEUP:
  845.       scroll -= fontH;
  846.       updateScroll = true;;
  847.       break;
  848.     case SB_LINEDOWN:
  849.       scroll += fontH;
  850.       updateScroll = true;;
  851.       break;
  852.     case SB_PAGEUP:
  853.       scroll -= rect.yTop-rect.yBottom;
  854.       updateScroll = true;;
  855.       break;
  856.     case SB_PAGEDOWN:
  857.       scroll += rect.yTop-rect.yBottom;
  858.       updateScroll = true;;
  859.       break;
  860.     case SB_SLIDERTRACK:
  861.     case SB_SLIDERPOSITION:
  862.       scroll = SHORT1FROMMP( mpParm2);
  863.                /*(USHORT) WinSendMsg(hwndVertScroll,
  864.                 SBM_QUERYPOS, (MPARAM) NULL, (MPARAM) NULL);*/
  865.       break;
  866.     case SB_ENDSCROLL:
  867.       break;
  868.     default:
  869.       break;
  870.     }
  871.  
  872.     if (updateScroll) {
  873.       WinQueryWindowRect(hwndClient, &rect);
  874.       tmp = DISP_LINES * fontH - (rect.yTop - rect.yBottom);
  875.       if (tmp < 0) tmp = 0;
  876.       if (scroll > tmp) scroll = tmp;
  877.       WinSendMsg( hwndVertScroll,
  878.                   SBM_SETSCROLLBAR,
  879.                   MPFROMSHORT(scroll),
  880.                   MPFROM2SHORT(0, tmp));
  881.       WinSendMsg( hwndVertScroll,
  882.                   SBM_SETTHUMBSIZE,
  883.                   MPFROM2SHORT(rect.yTop - rect.yBottom, DISP_LINES * fontH),
  884.                   NULL);
  885.     }
  886.  
  887.     tmp = DISP_LINES * fontH - (rect.yTop - rect.yBottom);
  888.     if (scroll > tmp) scroll = tmp;
  889.     if (scroll < 0) scroll = 0;
  890.  
  891.     WinScrollWindow(hwndClient, 0, scroll-oldscroll, NULL, NULL, NULLHANDLE, NULL, SW_INVALIDATERGN);
  892.     break;
  893.  
  894.   case WM_ERASEBACKGROUND:
  895.     return MRFROMSHORT ( false );  // No, we'll do this ourselves
  896.  
  897.   case WM_CHAR:
  898.      switch (CHARMSG(&ulMsg)->vkey)
  899.         {
  900.         case VK_UP:
  901.         case VK_DOWN:
  902.         case VK_PAGEUP:
  903.         case VK_PAGEDOWN:
  904.            return WinSendMsg(hwndVertScroll, ulMsg, mpParm1, mpParm2);
  905.         }
  906.  
  907.   default:
  908.     return WinDefWindowProc ( hwndWnd,
  909.                               ulMsg,
  910.                               mpParm1,
  911.                               mpParm2 );
  912.   }
  913.  
  914.   return MRFROMSHORT ( FALSE );
  915. }
  916.  
  917. void
  918. PostFin(int onlyupdate) {
  919.   if (onlyupdate) {
  920.     WinPostMsg(hwndClient, THR_UPDATE, NULL, NULL);
  921.   } else {
  922.     WinPostMsg(hwndClient, THR_DONE, NULL, NULL);
  923.   }
  924. }
  925.  
  926. void err(char* s) {
  927.   log(s);
  928.   ErrorBox(s);
  929.   exit(1);
  930. }
  931.  
  932. void warn(char* s) {
  933.   WarnBox(s);
  934. }
  935.  
  936. static void
  937. SetTitle(char* s) {
  938.   char tmp[100];
  939.   sprintf(tmp, "SysBench %s - %s", SYSB_VER, s);
  940.   WinSetWindowText(hwndFrame, tmp);
  941. }
  942.  
  943. static void
  944. UpdateWindow(HPS hpsPaint, PRECTL pRect, s32 scrollValue) {
  945.   static char tmp[256];
  946.   s32 i, comp;
  947.   s32 line = 0;
  948.  
  949.   // print header
  950.  
  951.   line++;
  952. //  line++;
  953.  
  954.   for (comp = 0; comp < NUM_COMPONENTS; comp++) {
  955.     // print title
  956.     Print(line, 1, data.c[comp].title, pRect, scrollValue, hpsPaint, CLR_GREEN);
  957.     line++;
  958.     // print lines of data
  959.     for (i = 0; i < data.c[comp].ndatalines; i++) {
  960.       if (data.c[comp].datalines[i].value < 0.0)
  961.         sprintf(tmp, "%-21s :       --.---    %s", data.c[comp].datalines[i].entry,
  962.                 data.c[comp].datalines[i].unit);
  963.       else
  964.         sprintf(tmp, "%-21s : %12.3f    %s", data.c[comp].datalines[i].entry,
  965.                 data.c[comp].datalines[i].value / data.c[comp].datalines[i].unit_val,
  966.                 data.c[comp].datalines[i].unit);
  967.       Print(line, 3, tmp, pRect, scrollValue, hpsPaint, CLR_WHITE);
  968.       line++;
  969.     }
  970.     Print(line, 3, "────────────────────────────────────────────────────────────", pRect, scrollValue, hpsPaint, CLR_PALEGRAY);
  971.     line++;
  972.     if (data.c[comp].total < 0.0)
  973.       sprintf(tmp, "Total                 :       --.---    %s",
  974.               data.c[comp].unit_total);
  975.     else
  976.       sprintf(tmp, "Total                 : %12.3f    %s", data.c[comp].total,
  977.               data.c[comp].unit_total);
  978.     Print(line, 3, tmp, pRect, scrollValue, hpsPaint, CLR_YELLOW);
  979.     line++;
  980.     line++;
  981.   }
  982. }
  983.  
  984. static void
  985. Print(s32 row, s32 col, char* string, PRECTL pRect, s32 scrollValue, HPS hpsPaint, s32 color)
  986.  {
  987.   RECTL printRect;
  988.  
  989.   printRect.xLeft = col * fontW;
  990.   printRect.xRight = pRect->xRight;
  991.   printRect.yTop = pRect->yTop - row * fontH + scrollValue;
  992.   printRect.yBottom = printRect.yTop - fontH;
  993.  
  994.   WinDrawText(hpsPaint, -1, (PCH)string, &printRect, color, CLR_BLACK, DT_TOP | DT_LEFT);
  995. }
  996.  
  997. static void
  998. PrintFile(s32 newlines, s32 col, char* string, FILE* fp) {
  999.   s32 i;
  1000.   for (i = 0; i < col; i++)
  1001.     fprintf(fp, " ");
  1002.  
  1003.   fprintf(fp, "%s", string);
  1004.  
  1005.   for (i = 0; i < newlines; i++)
  1006.     fprintf(fp, "\n");
  1007. }
  1008.  
  1009. void
  1010. InfoBox(char* s) {
  1011.   WinMessageBox(HWND_DESKTOP,
  1012.                 hwndFrame,
  1013.                 s,
  1014.                 "Info",
  1015.                 WND_MESSAGEB,
  1016.                 MB_OK | MB_INFORMATION | MB_APPLMODAL | MB_MOVEABLE);
  1017. }
  1018.  
  1019.  
  1020. void
  1021. ErrorBox(char* s) {
  1022.   WinMessageBox(HWND_DESKTOP,
  1023.                 hwndFrame,
  1024.                 s,
  1025.                 "Error !",
  1026.                 WND_MESSAGEB,
  1027.                 MB_OK | MB_ERROR | MB_APPLMODAL | MB_MOVEABLE);
  1028. }
  1029.  
  1030.  
  1031. void
  1032. WarnBox(char* s) {
  1033.   WinMessageBox(HWND_DESKTOP,
  1034.                 hwndFrame,
  1035.                 s,
  1036.                 "Warning !",
  1037.                 WND_MESSAGEB,
  1038.                 MB_OK | MB_WARNING | MB_APPLMODAL | MB_MOVEABLE);
  1039. }
  1040.  
  1041. void
  1042. UpdateAll(void) {
  1043.   RECTL rclWindow, cliprect;
  1044.   HRGN  newHrgn, oldHrgn, dummy;
  1045.   s32 i, comp;
  1046.   bool calcav = true;
  1047.  
  1048.  
  1049.   // calculate averages
  1050.   for (comp = 0; comp < NUM_COMPONENTS; comp++) {
  1051.     calcav = true;
  1052.     for (i = 0; i < data.c[comp].ndatalines; i++) {
  1053.       calcav = calcav && (data.c[comp].datalines[i].value >= 0.0);
  1054.     }
  1055.     if (!calcav)
  1056.       continue;
  1057.     switch (comp) {
  1058.     case comp_gfx:
  1059.       data.c[comp_gfx].total = CalcGfxAv();
  1060.       break;
  1061.     case comp_cpuint:
  1062.       data.c[comp_cpuint].total = CalcCPUIntAv();
  1063.       break;
  1064.     case comp_cpufloat:
  1065.       data.c[comp_cpufloat].total = CalcCPUFloatAv();
  1066.       break;
  1067.     case comp_mem:
  1068.       data.c[comp_mem].total = CalcMemAv();
  1069.       break;
  1070.     case comp_dive:
  1071.       data.c[comp_dive].total = CalcDIVEAv();
  1072.       break;
  1073.     case comp_disk:
  1074.       data.c[comp_disk].total = CalcDiskIOAv();
  1075.       break;
  1076.     }
  1077.   }
  1078.  
  1079.   // update screen
  1080.   WinQueryWindowRect ( hwndClient, &rclWindow ); // update whole window
  1081.   cliprect.xLeft = rclWindow.xLeft;
  1082.   cliprect.xRight = rclWindow.xRight+1;
  1083.   cliprect.yBottom = rclWindow.yBottom;
  1084.   cliprect.yTop = rclWindow.yTop+1;
  1085.   newHrgn = GpiCreateRegion(mainHps, 1, &cliprect);
  1086.   GpiSetClipRegion(mainHps, newHrgn, &oldHrgn);
  1087.   if (NULLHANDLE != oldHrgn)
  1088.     GpiDestroyRegion(mainHps, oldHrgn);
  1089.   UpdateWindow(mainHps, &rclWindow, scroll);
  1090.   oldscroll = scroll;
  1091. }
  1092.  
  1093. static void SetMenuState(bool active) { // if active == true => all items enabled
  1094.                                         // otherw. all items but the about and close are disabled
  1095.   WinEnableMenuItem(hwndMenu, MI_PROJ_SAVE, active);
  1096.   WinEnableMenuItem(hwndMenu, MI_PROJ_ALL, active);
  1097.   WinEnableMenuItem(hwndMenu, MI_MENU_GFX, active);
  1098.   WinEnableMenuItem(hwndMenu, MI_MENU_CPUINT, active);
  1099.   WinEnableMenuItem(hwndMenu, MI_MENU_CPUFLOAT, active);
  1100.   WinEnableMenuItem(hwndMenu, MI_MENU_MEM, active);
  1101.   WinEnableMenuItem(hwndMenu, MI_MENU_DIVE, active);
  1102.   if (data.nr_fixed_disks)
  1103.     WinEnableMenuItem(hwndMenu, MI_MENU_DISKIO, active);
  1104. }
  1105.  
  1106.  
  1107. static void SaveResults(void) {
  1108.   FILE* fp;
  1109.   static char tmp[256];
  1110.   s32 i, comp;
  1111.   struct tm *newtime;
  1112.   time_t ltime;
  1113.  
  1114.   FILEDLG fild;            /* File dialog info structure           */
  1115.   char pszTitle[24] = "Save Results to file..."; /* Title of dialog              */
  1116.   char pszFullFile[CCHMAXPATH] = "RESULT.TXT";/* File filter string       */
  1117.   HWND hwndDlg;            /* File dialog window */
  1118.  
  1119.   BYTE coproc;
  1120.   ULONG value[QSV_MAX] = {0};
  1121.   APIRET rc = 0UL;
  1122.   double meg = MB;
  1123.  
  1124.   ULONG   ulCategory       = IOCTL_OEMHLP;         /* Device category */
  1125.   ULONG   ulFunction       = OEMHLP_GETMACHINEINFO; /* Device-specific function */
  1126.   UCHAR   uchParms[1]      = {0};          /* Input and output for function */
  1127.   ULONG   ulParmLen        = 1;            /* Input and output parameter size */
  1128.   UCHAR   uchDataArea[40] = {0};                 /* Input and output data area */
  1129.   ULONG   ulDataLen        = 40;            /* Input and output data size */
  1130.  
  1131.   HFILE filehandle;
  1132.   ULONG action;
  1133.  
  1134. /*  rc = DosOpen("OEMHLP$",
  1135.                &filehandle,
  1136.                &action,
  1137.                0L,
  1138.                0,
  1139.                1,
  1140.                0x40,
  1141.                0L);
  1142.   if (rc == 0)
  1143.      {
  1144.       ulParmLen = strlen(uchParms);   /* Length of input parameters */
  1145.  
  1146.  /*     rc = DosDevIOCtl(filehandle,           /* Handle to device */
  1147.  //                      ulCategory,          /* Category of request */
  1148.  //                      ulFunction,          /* Function being requested */
  1149.  //                      uchParms,            /* Input/Output parameter list */
  1150.  //                      sizeof(uchParms),    /* Maximum output parameter size */
  1151.  //                      &ulParmLen,          /* Input:  size of parameter list */
  1152.                                             /* Output: size of parameters returned */
  1153.  //                      uchDataArea,         /* Input/Output data area */
  1154.  //                      sizeof(uchDataArea), /* Maximum output data size */
  1155.  //                     &ulDataLen);         /* Input:  size of input data area */
  1156.                                             /* Output: size of data returned   */
  1157.  //      }
  1158.  // DosClose(filehandle);             /* Close handle to OEMHLP$ */
  1159.  
  1160.   memset(&fild, 0, sizeof(FILEDLG)); /* set fields in file dlg to zero */
  1161.  
  1162.   fild.cbSize = sizeof(FILEDLG);       /* Size of structure        */
  1163.   fild.fl = FDS_CENTER | FDS_SAVEAS_DIALOG | FDS_ENABLEFILELB      ;
  1164.                                     /* FDS_* flags              */
  1165.   fild.pszTitle = pszTitle;         /* Dialog title string         */
  1166.   strcpy(fild.szFullFile, pszFullFile);  /* Initial path,file name, or file filter */
  1167.  
  1168.   hwndDlg = WinFileDlg(HWND_DESKTOP, hwndClient, &fild);
  1169.  
  1170.   if (hwndDlg && (fild.lReturn == DID_OK))
  1171.      {
  1172.      fp = fopen(fild.szFullFile, "wb");
  1173.      if (!fp)
  1174.         {
  1175.         WarnBox("Cannot open output file");
  1176.         return;
  1177.         }
  1178.      }
  1179.   else
  1180.      {
  1181.      return;
  1182.      }
  1183.  
  1184.   DosDevConfig(&coproc,DEVINFO_COPROCESSOR);
  1185.  
  1186.   rc = DosQuerySysInfo(QSV_DYN_PRI_VARIATION, QSV_TOTPHYSMEM, (PVOID)value, sizeof(ULONG)*QSV_MAX);
  1187.  
  1188.   time(<ime);
  1189.   newtime = localtime(<ime);
  1190.   fprintf(fp, "\n\nSysbench " SYSB_VER " result file created %s\n", asctime(newtime));
  1191.  
  1192.   fprintf(fp, "Coprocessor = %s, RAM = %3.2f MB\nPriority=%s, Maxwait=%d, Timeslice=(%d,%d).\n\n",
  1193.                (coproc ? "Yes" : "No"),
  1194.                (double)value[QSV_TOTPHYSMEM - QSV_DYN_PRI_VARIATION]/meg,
  1195.                (value[QSV_MAX_WAIT - QSV_DYN_PRI_VARIATION] ? "Dynamic" : "Absolute"),
  1196.                value[QSV_MAX_WAIT - QSV_DYN_PRI_VARIATION],
  1197.                value[QSV_MIN_SLICE - QSV_DYN_PRI_VARIATION],
  1198.                value[QSV_MAX_SLICE - QSV_DYN_PRI_VARIATION]);
  1199.  
  1200.   for (comp = 0; comp < NUM_COMPONENTS; comp++) {
  1201.     // print title
  1202.     PrintFile(1, 1, data.c[comp].title, fp);
  1203.     // print lines of data
  1204.     for (i = 0; i < data.c[comp].ndatalines; i++) {
  1205.       if (data.c[comp].datalines[i].value < 0.0)
  1206.         sprintf(tmp, "%-21s :       --.---    %s", data.c[comp].datalines[i].entry,
  1207.                 data.c[comp].datalines[i].unit);
  1208.       else
  1209.         sprintf(tmp, "%-21s : %12.3f    %s", data.c[comp].datalines[i].entry,
  1210.                 data.c[comp].datalines[i].value / data.c[comp].datalines[i].unit_val,
  1211.                 data.c[comp].datalines[i].unit);
  1212.       PrintFile(1, 3, tmp, fp);
  1213.     }
  1214. //  PrintFile(1, 3, "────────────────────────────────────────────────────────────", fp);
  1215.     PrintFile(1, 3, "------------------------------------------------------------", fp);
  1216.     if (data.c[comp].total < 0.0)
  1217.       sprintf(tmp, "Total                 :       --.---    %s",
  1218.               data.c[comp].unit_total);
  1219.     else
  1220.       sprintf(tmp, "Total                 : %12.3f    %s", data.c[comp].total,
  1221.               data.c[comp].unit_total);
  1222.     PrintFile(2, 3, tmp, fp);
  1223.   }
  1224.  
  1225.   fclose(fp);
  1226. }
  1227.  
  1228.  
  1229.